aboutsummaryrefslogtreecommitdiff
path: root/src/app/(main)/websites/[websiteId]/sessions/SessionActivity.tsx
blob: cbb2810835e5792fda492f41a5e6112ffcd21894 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import {
  Button,
  Column,
  Dialog,
  DialogTrigger,
  Heading,
  Icon,
  Popover,
  Row,
  StatusLight,
  Text,
} from '@umami/react-zen';
import { isSameDay } from 'date-fns';
import { LoadingPanel } from '@/components/common/LoadingPanel';
import { useMessages, useMobile, useSessionActivityQuery, useTimezone } from '@/components/hooks';
import { Eye, FileText } from '@/components/icons';
import { EventData } from '@/components/metrics/EventData';
import { Lightning } from '@/components/svg';

export function SessionActivity({
  websiteId,
  sessionId,
  startDate,
  endDate,
}: {
  websiteId: string;
  sessionId: string;
  startDate: Date;
  endDate: Date;
}) {
  const { formatMessage, labels } = useMessages();
  const { formatTimezoneDate } = useTimezone();
  const { data, isLoading, error } = useSessionActivityQuery(
    websiteId,
    sessionId,
    startDate,
    endDate,
  );
  const { isMobile } = useMobile();
  let lastDay = null;

  return (
    <LoadingPanel data={data} isLoading={isLoading} error={error}>
      <Column gap>
        {data?.map(({ eventId, createdAt, urlPath, eventName, visitId, hasData }) => {
          const showHeader = !lastDay || !isSameDay(new Date(lastDay), new Date(createdAt));
          lastDay = createdAt;

          return (
            <Column key={eventId} gap>
              {showHeader && <Heading size="1">{formatTimezoneDate(createdAt, 'PPPP')}</Heading>}
              <Row alignItems="center" gap="6" height="40px">
                <StatusLight color={`#${visitId?.substring(0, 6)}`}>
                  <Text wrap="nowrap">{formatTimezoneDate(createdAt, 'pp')}</Text>
                </StatusLight>
                <Row alignItems="center" gap="2">
                  <Icon>{eventName ? <Lightning /> : <Eye />}</Icon>
                  <Text wrap="nowrap">
                    {eventName
                      ? formatMessage(labels.triggeredEvent)
                      : formatMessage(labels.viewedPage)}
                  </Text>
                  <Text weight="bold" style={{ maxWidth: isMobile ? '400px' : null }} truncate>
                    {eventName || urlPath}
                  </Text>
                  {hasData > 0 && <PropertiesButton websiteId={websiteId} eventId={eventId} />}
                </Row>
              </Row>
            </Column>
          );
        })}
      </Column>
    </LoadingPanel>
  );
}

const PropertiesButton = props => {
  return (
    <DialogTrigger>
      <Button variant="quiet">
        <Row alignItems="center" gap>
          <Icon>
            <FileText />
          </Icon>
        </Row>
      </Button>
      <Popover placement="right">
        <Dialog>
          <EventData {...props} />
        </Dialog>
      </Popover>
    </DialogTrigger>
  );
};